home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Coswitch for Icon V8 interpreter running in 32 bit protected mode
- ; with MetaWare High C 386 (PharLap DOS|Extender) or Intel 386/486
- ; C Code Builder Kit.
- ;
- ; Author: Robert Goldberg
- ;
- ; Note: Assemble with PharLap assembler and -twocase switch to
- ; preserve lower-case public names (important for Intel linker).
- ;
- ; Coswitch algorithm in C:
- ;
- ; coswitch( old_cs, new_cs, first )
- ; int *old_cs, *new_cs, first;
- ; {
- ; /* save SP, frame pointers, and other registers in old_cs */
- ; if ( first == 0 )
- ; {
- ; /* load sp from new_sp[0] and clear frame pointers */
- ; interp( 0, 0 );
- ; syserr( "interp() returned in coswitch" );
- ; }
- ; else
- ; {
- ; /* load sp, frame pointers and other registers from new_cs */
- ; }
- ; }
- ;
- ; Define external functions:
- ;
- .386
- extrn interp:near
- extrn runerr:near
- ;
- ; Define error message in appropriate segment and group.
- ;
- dgroup group asmdata
- assume ds:dgroup
- public errormsg
- asmdata segment dword public 'DATA'
- errormsg db 'interp() returned in coswitch',0
- asmdata ends
- ;
- ; Define function coswitch in appropriate segment and group.
- ;
- cgroup group asmcode
- assume cs:cgroup
- asmcode segment dword 'CODE'
- public coswitch
- db 'coswitch',8
- coswitch proc near
- ;
- ; Save environment at point of call.
- ;
- ; According to MetaWare's documentation (Chapter 9 - Run-Time Organization)
- ; registers EAX, ECX, EDX, FS, GS, and sometimes ES are volatile. So, a
- ; function must preserve registers EBP, ESI, EDI, and EBX across calls.
- ; So, save all these registers plus ESP in area pointed to by old_cs.
- ;
- mov edx,4[esp] ; point to old_cs
- mov 0[edx],esp ; save esp
- mov 4[edx],ebp ; save ebp
- mov 8[edx],esi ; save esi
- mov 12[edx],edi ; save edi
- mov 16[edx],ebx ; save ebx
- ;
- ; Check first flag to see if first activation of this coexpression.
- ;
- mov eax,12[esp] ; load first flag
- or eax,eax ; set condition flags
- jnz notzero ; jump if not zero
- ;
- ; First is 0 -
- ;
- ; Set things up for first activation of this coexpression.
- ;
- mov edx,8[esp] ; point to new_cs area
- mov esp,0[edx] ; set ESP from new_cs
- mov ebp,esp ; set EBP equal to ESP (can't hurt?)
- xor eax,eax ; get a zero
- mov esi,eax ; clear ESI
- mov edi,eax ; clear EDI
- push eax ; push two zeros
- push eax ; onto stack
- call interp ; interp(0,0) - should not return!
- push offset errormsg ; push offset to error messgae
- call runerr ; terminate with error
- ;
- ; First is not 0 -
- ;
- ; Restore environment from new_cs.
- ;
- notzero:
- mov edx,8[esp] ; point to new_cs
- mov esp,0[edx] ; restore esp
- mov ebp,4[edx] ; restore ebp
- mov esi,8[edx] ; restore esi
- mov edi,12[edx] ; restore edi
- mov ebx,16[edx] ; restore ebx
- ret ; return
- coswitch endp
- asmcode ends
- end
-